﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;

namespace Windstamp.Utility.BookDownload.Common {
    /// <summary>
    /// Cookie 助手类
    /// </summary>
    public class CookiesHelper {
        /// <summary>
        /// 一个到多个Cookie的字符串添加到CookieCollection集合中
        /// </summary>
        /// <param name="cookieString">Cookie的字符串</param>
        /// <param name="defaultDomain">站点主机部分</param>
        public static CookieCollection String2CookieCollection(string cookieString, string defaultDomain) {
            CookieCollection collection = new CookieCollection();
            if(string.IsNullOrEmpty(cookieString) || cookieString.Length < 5 || cookieString.IndexOf("=") < 0)
                return collection;
            if(string.IsNullOrEmpty(defaultDomain) || defaultDomain.Length < 5)
                return collection;
            cookieString.TrimEnd(new char[] { ';' }).Trim();
            Uri urI = new Uri(defaultDomain);
            defaultDomain = urI.Host.ToString();
            //用软件截取的cookie会带有expires，要把它替换掉
            if(cookieString.IndexOf("expires=") >= 0) {
                cookieString = replace(cookieString, @"expires=[\w\s,-:]*GMT[;]?", "");
            }
            //只有一个cookie直接添加
            if(cookieString.IndexOf(";") < 0) {
                System.Net.Cookie c = new System.Net.Cookie(cookieString.Substring(0, cookieString.IndexOf("=")), cookieString.Substring(cookieString.IndexOf("=") + 1));
                c.Domain = defaultDomain;
                collection.Add(c);
                return collection;
            }
            //不同站点与不同路径一般是以英文道号分别
            if(cookieString.IndexOf(",") > 0) {
                cookieString.TrimEnd(new char[] { ',' }).Trim();
                foreach(string s2 in cookieString.Split(',')) {
                    collection = StringAdd2CookieCollection(s2, defaultDomain, collection);
                }
                return collection;
            }
                //同站点与同路径,不同.Name与.Value
            else {
                return StringAdd2CookieCollection(cookieString, defaultDomain, collection);
            }
        }
        //添加到CookieCollection集合部分
        private static CookieCollection StringAdd2CookieCollection(string s, string defaultDomain, CookieCollection cc) {
            try {
                s.TrimEnd(new char[] { ';' }).Trim();
                System.Collections.Hashtable hs = new System.Collections.Hashtable();
                foreach(string s2 in s.Split(';')) {
                    string s3 = s2.Trim();
                    if(s3.IndexOf("=") > 0) {
                        string[] s4 = s3.Split('=');
                        hs.Add(s4[0].Trim(), s4[1].Trim());
                    }
                }
                string defaultPath = "/";
                foreach(object Key in hs.Keys) {
                    if(Key.ToString().ToLower() == "path") {
                        defaultPath = hs[Key].ToString();
                    } else if(Key.ToString().ToLower() == "domain") {
                        defaultDomain = hs[Key].ToString();
                    }
                }
                foreach(object Key in hs.Keys) {
                    if(!string.IsNullOrEmpty(Key.ToString()) && !string.IsNullOrEmpty(hs[Key].ToString())) {
                        if(Key.ToString().ToLower() != "path" && Key.ToString().ToLower() != "domain") {
                            Cookie c = new Cookie();
                            c.Name = Key.ToString();
                            c.Value = hs[Key].ToString();
                            c.Path = defaultPath;
                            c.Domain = defaultDomain;
                            cc.Add(c);
                        }
                    }
                }
            } catch { }
            return cc;
        }

        /// <summary>
        /// 替换字符
        /// </summary>
        /// <param name="strSource">来源</param>
        /// <param name="strRegex">表达式</param>
        /// <param name="strReplace">取代</param>
        public static string replace(string strSource, string strRegex, string strReplace) {
            try {
                Regex r;
                r = new Regex(strRegex, RegexOptions.IgnoreCase | RegexOptions.Singleline);
                string s = r.Replace(strSource, strReplace);
                return s;
            } catch {
                return strSource;
            }
        }
    }
}
